home *** CD-ROM | disk | FTP | other *** search
-
- /**
- * My first GLUT prog.
- * Uses most GLUT calls to prove it all works.
- * G Edwards, 30 Aug 95.
- *
- * Notes:
- * Display lists are not shared between windows, and there doesn't seem to be
- * any provision for this in GLUT. See glxCreateContext.
- *
- * The windows are internally indexed 0,1,2,3,4,5,6. The actual window ids
- * returned by glut are held in winId[0], ...
- *
- * Todo:
- *
- * Could reorder the windows so 0,1,2,3,4,5,6 are the gfx, 7,8 text.
- *
- * 30 Aug 95 GJE Created. Version 1.00
- * 05 Sep 95 GJE Version 1.01.
- * 07 Sep 95 GJE Version 1.02. More or less complete. All possible GLUT
- * calls used, except dials/buttons/tablet/spaceball stuff.
- * 15 Sep 95 GJE Add "trackball" code.
- *
- * Calls not used yet: these callbacks are registered but inactive.
- *
- * glutSpaceball<xxx>Func
- * glutButtonBoxFunc
- * glutDialsFunc
- * glutTabletMotionFunc
- * glutTabletButtonFunc
- *
- * Tested on:
- * R3K Indigo Starter
- * R4K Indigo Elan
- * R4K Indy XZ
- * R4K Indy XL
- * R4K Indigo2 Extreme
- */
-
- #include <GL/glut.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
-
- /* Controls */
-
- #define VERSION "1.00"
- #define DATE "16Sep95"
- #define DELAY 1000 /* delay for timer test */
- #define MENUDELAY 200 /* hack to fix glutMenuStateFunc bug */
- #define MAXWIN 9 /* max no. of windows */
-
- unsigned int AUTODELAY = 1500; /* delay in demo mode */
-
- #define VERSIONLONG "Version " VERSION "/" DATE ", compiled " __DATE__ ", " __TIME__ ", file " __FILE__
-
- int pos[MAXWIN][2] =
- {
- {50, 150}, /* win 0 */
- {450, 150}, /* win 1 */
- {50, 600}, /* win 2 */
- {450, 600}, /* win 3 */
- {10, 10}, /* subwin 4 (relative to parent win 0) */
- {300, 400}, /* help win 5 */
- {850, 150}, /* cmap win 6 */
- {850, 600}, /* cmap win 7 */
- {250, 450} /* text win 8 */
- };
-
- int size[MAXWIN][2] =
- {
- {350, 350}, /* win 0 */
- {350, 350}, /* win 1 */
- {350, 350}, /* win 2 */
- {350, 350}, /* win 3 */
- {200, 200}, /* subwin 4 */
- {700, 300}, /* help win 5 */
- {350, 350}, /* cmap win 6 */
- {350, 350}, /* cmap win 7 */
- {800, 450} /* text win 8 */
- };
-
- /* Macros */
-
- #define PR if(debug)printf
-
- /* #define GLNEWLIST(a, b) glNewList(a, b), fprintf(stderr,
- "creating list %d \n", a); */
- /* #define GLCALLLIST(a) glCallList(a), fprintf(stderr,
- "calling list %d \n", a); */
- /* #define GLUTSETWINDOW(x) glutSetWindow(x), fprintf(stderr,
- "gsw at %d\n", __LINE__) */
-
- /* Globals */
-
- int winId[MAXWIN] =
- {0}; /* table of glut window id's */
- GLboolean winVis[MAXWIN] =
- {GL_FALSE}; /* is window visible */
-
- GLboolean text[MAXWIN] =
- {GL_FALSE}; /* is text on */
- GLboolean winFreeze[MAXWIN] =
- {GL_FALSE}; /* user requested menuFreeze */
- GLboolean menuFreeze = GL_FALSE; /* menuFreeze while menus posted */
- GLboolean timerOn = GL_FALSE; /* timer active */
- GLboolean animation = GL_TRUE; /* idle func animation on */
- GLboolean debug = GL_FALSE; /* dump all events */
- GLboolean showKeys = GL_FALSE; /* dump key events */
- GLboolean demoMode = GL_FALSE; /* run automatic demo */
- GLboolean backdrop = GL_FALSE; /* use backdrop polygon */
- GLboolean passive = GL_FALSE; /* report passive motions */
- GLboolean leftDown = GL_FALSE; /* left button down ? */
- GLboolean middleDown = GL_FALSE; /* middle button down ? */
-
- int displayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH;
- int currentShape = 0; /* current glut shape */
- int scrollLine = 0, scrollCol = 0; /* help scrolling params */
- int lineWidth = 1; /* line width */
- int angle = 0; /* global rotation angle */
- char *textPtr[1000] =
- {0}; /* pointers to text window text */
- int textCount = 0, helpCount = 0; /* text list indexes */
- float scaleFactor = 0.0; /* window size scale factor */
-
- #ifdef ALPHA
- #undef ALPHA /* Avoid problems with DEC's ALPHA machines. */
- #endif
-
- int menu1, menu2, menu3, menu4, menu5, menu6 = 0, menu7, menu8;
- enum {
- RGBA, INDEX, SINGLE, DOUBLEBUFFER, DEPTH, ACCUM, ALPHA, STENCIL, MULTISAMPLE,
- STEREO, MODES
- };
- char *modeNames[] =
- {"RGBA", "INDEX", "SINGLE", "DOUBLE", "DEPTH", "ACCUM",
- "ALPHA", "STENCIL", "MULTISAMPLE", "STEREO"};
- int glutMode[] =
- {GLUT_RGBA, GLUT_INDEX, GLUT_SINGLE, GLUT_DOUBLE, GLUT_DEPTH,
- GLUT_ACCUM, GLUT_ALPHA, GLUT_STENCIL, GLUT_MULTISAMPLE, GLUT_STEREO};
- int modes[MODES] =
- {0};
- GLboolean menuButton[3] =
- {0, 0, 1};
- enum {
- MOUSEBUTTON, MOUSEMOTION, APPLY, RESET
- };
-
- /* Prototypes */
-
- void gfxInit(int);
- void drawScene(void);
- void idleFunc(void);
- void reshapeFunc(int width, int height);
- void visible(int state);
- void keyFunc(unsigned char key, int x, int y);
- void mouseFunc(int button, int state, int x, int y);
- void motionFunc(int x, int y);
- void passiveMotionFunc(int x, int y);
- void entryFunc(int state);
- void specialFunc(int key, int x, int y);
- void menuStateFunc(int state);
- void timerFunc(int value);
- #if 0
- void delayedReinstateMenuStateCallback(int value);
- #endif
- void menuFunc(int value);
- void showText(void);
- void textString(int x, int y, char *str, void *font);
- void strokeString(int x, int y, char *str, void *font);
- void makeMenus(void);
- int idToIndex(int id);
- void setInitDisplayMode(void);
- void createMenu6(void);
- void removeCallbacks(void);
- void addCallbacks(void);
- void dumpIds(void);
- void updateHelp(void);
- void updateAll(void);
- void killWindow(int index);
- void makeWindow(int index);
- void warning(char *msg);
- void autoDemo(int);
- void positionWindow(int index);
- void reshapeWindow(int index);
- void iconifyWindow(int index);
- void showWindow(int index);
- void hideWindow(int index);
- void pushWindow(int index);
- void popWindow(int index);
- void attachMenus(void);
- void killAllWindows(void);
- void makeAllWindows(void);
- void updateText(void);
- void updateScrollWindow(int index, char **ptr);
- void redefineShapes(int shape);
- GLboolean match(char *, char *);
- void checkArgs(int argc, char *argv[]);
- void scaleWindows(float);
- void commandLineHelp(void);
- void trackBall(int mode, int button, int state, int x, int y);
-
- void spaceballMotionCB(int, int, int);
- void spaceballRotateCB(int, int, int);
- void spaceballButtonCB(int, int);
- void buttonBoxCB(int, int);
- void dialsCB(int, int);
- void tabletMotionCB(int, int);
- void tabletButtonCB(int, int, int, int);
-
- /* strdup is actually not a standard ANSI C or POSIX routine
- so implement a private one. OpenVMS does not have a strdup; Linux's
- standard libc doesn't declare strdup by default (unless BSD or SVID
- interfaces are requested). */
- static char *
- stralloc(const char *string)
- {
- char *copy;
-
- copy = malloc(strlen(string) + 1);
- if (copy == NULL)
- return NULL;
- strcpy(copy, string);
- return copy;
- }
-
- /* main */
-
- int
- main(int argc, char **argv)
- {
-
- /* General init */
-
- glutInit(&argc, argv);
-
- /* Check args */
-
- checkArgs(argc, argv);
-
- /* Scale window position/size if needed. Ignore aspect ratios. */
-
- if (scaleFactor > 0.0)
- scaleWindows(scaleFactor);
- else
- scaleWindows(glutGet(GLUT_SCREEN_WIDTH) / 1280.0);
-
- /* Set initial display mode */
-
- modes[RGBA] = 1;
- modes[DOUBLEBUFFER] = 1;
- modes[DEPTH] = 1;
- setInitDisplayMode();
-
- /* Set up menus */
-
- makeMenus();
-
- /* Make some windows */
-
- makeWindow(0);
- makeWindow(1);
-
- /* Global callbacks */
-
- glutIdleFunc(idleFunc);
- glutMenuStateFunc(menuStateFunc);
-
- /* Start demo if needed */
-
- if (demoMode)
- autoDemo(-2);
-
- /* Fall into event loop */
-
- glutMainLoop();
- return 0; /* ANSI C requires main to return int. */
- }
-
- /* gfxInit - Init opengl for each window */
-
- void
- gfxInit(int index)
- {
- GLfloat grey10[] =
- {0.10, 0.10, 0.10, 1.0};
- GLfloat grey20[] =
- {0.2, 0.2, 0.2, 1.0};
- GLfloat black[] =
- {0.0, 0.0, 0.0, 0.0};
- GLfloat diffuse0[] =
- {1.0, 0.0, 0.0, 1.0};
- GLfloat diffuse1[] =
- {0.0, 1.0, 0.0, 1.0};
- GLfloat diffuse2[] =
- {1.0, 1.0, 0.0, 1.0};
- GLfloat diffuse3[] =
- {0.0, 1.0, 1.0, 1.0};
- GLfloat diffuse4[] =
- {1.0, 0.0, 1.0, 1.0};
-
- #define XX 3
- #define YY 3
- #define ZZ -2.5
-
- float vertex[][3] =
- {
- {-XX, -YY, ZZ},
- {+XX, -YY, ZZ},
- {+XX, +YY, ZZ},
- {-XX, +YY, ZZ}
- };
-
- /* warning: This func mixes RGBA and CMAP calls in an ugly
- fashion */
-
- redefineShapes(currentShape); /* set up display lists */
- glutSetWindow(winId[index]); /* hack - redefineShapes
- changes glut win */
-
- /* Shaded backdrop square (RGB or CMAP) */
-
- glNewList(100, GL_COMPILE);
- glPushAttrib(GL_LIGHTING);
- glDisable(GL_LIGHTING);
- glBegin(GL_POLYGON);
-
- glColor4fv(black);
- glIndexi(0);
- glVertex3fv(vertex[0]);
-
- glColor4fv(grey10);
- glIndexi(3);
- glVertex3fv(vertex[1]);
-
- glColor4fv(grey20);
- glIndexi(4);
- glVertex3fv(vertex[2]);
-
- glColor4fv(grey10);
- glIndexi(7);
- glVertex3fv(vertex[3]);
-
- glEnd();
- glPopAttrib();
- glIndexi(9);
- glEndList();
-
- /* Set proj+view */
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(40.0, 1.0, 1.0, 20.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.);
- glTranslatef(0.0, 0.0, -1.0);
-
- if (index == 6 || index == 7)
- goto colorindex;
-
- /* Set basic material, lighting for RGB windows */
-
- if (index == 0)
- glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse0);
- else if (index == 1)
- glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse1);
- else if (index == 2)
- glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse2);
- else if (index == 3)
- glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse3);
- else if (index == 4)
- glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse4);
-
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glEnable(GL_DEPTH_TEST);
-
- if (index == 4)
- glClearColor(0.15, 0.15, 0.15, 1);
- else
- glClearColor(0.1, 0.1, 0.1, 1.0);
-
- return;
-
- /* Set GL basics for CMAP windows 6,7 */
-
- colorindex:
-
- glEnable(GL_DEPTH_TEST);
- if (glutGet(GLUT_WINDOW_COLORMAP_SIZE) < 16)
- warning("Color map size too small for color index window");
-
- /* Try to reuse an existing color map */
-
- if ((index == 6) && (winId[7] != 0)) {
- glutCopyColormap(winId[7]);
- } else if ((index == 7) && (winId[6] != 0)) {
- glutCopyColormap(winId[6]);
- } else {
- glutSetColor(8, 0.1, 0.1, 0.1);
- glutSetColor(9, 1.0, 0.5, 0.0);
- glutSetColor(10, 1.0, 0.6, 0.8);
- }
- glClearIndex(8);
- glIndexi(index + 3);
-
- }
-
- /* makeMenus - Create popup menus */
-
- void
- makeMenus(void)
- {
-
- /* General control / debug */
-
- menu2 = glutCreateMenu(menuFunc);
- glutAddMenuEntry("toggle auto demo mode (a)", 312);
- glutAddMenuEntry("toggle freezing in menus", 300);
- glutAddMenuEntry("toggle text per window (t)", 301);
- glutAddMenuEntry("toggle global timer", 302);
- glutAddMenuEntry("toggle global animation", 303);
- glutAddMenuEntry("toggle per window animation", 304);
- glutAddMenuEntry("toggle debug prints (D)", 305);
- glutAddMenuEntry("toggle shaded backdrop", 307);
- glutAddMenuEntry("toggle passive motion callback", 308);
- glutAddMenuEntry("increase line width (l)", 310);
- glutAddMenuEntry("decrease line width (L)", 311);
-
- /* Shapes */
-
- menu3 = glutCreateMenu(menuFunc);
- glutAddMenuEntry("sphere", 200);
- glutAddMenuEntry("cube", 201);
- glutAddMenuEntry("cone", 202);
- glutAddMenuEntry("torus", 203);
- glutAddMenuEntry("dodecahedron", 204);
- glutAddMenuEntry("octahedron", 205);
- glutAddMenuEntry("tetrahedron", 206);
- glutAddMenuEntry("icosahedron", 207);
- glutAddMenuEntry("teapot", 208);
-
- /* Open/close windows */
-
- menu4 = glutCreateMenu(menuFunc);
- glutAddMenuEntry("open all windows", 450);
- glutAddMenuEntry("close all windows", 451);
- glutAddMenuEntry(" ", 9999);
- glutAddMenuEntry("create win 0", 400);
- glutAddMenuEntry("create win 1", 401);
- glutAddMenuEntry("create win 2", 402);
- glutAddMenuEntry("create win 3", 403);
- glutAddMenuEntry("create sub window", 404);
- glutAddMenuEntry("create color index win 6", 406);
- glutAddMenuEntry("create color index win 7", 407);
- glutAddMenuEntry(" ", 9999);
- glutAddMenuEntry("destroy win 0", 410);
- glutAddMenuEntry("destroy win 1", 411);
- glutAddMenuEntry("destroy win 2", 412);
- glutAddMenuEntry("destroy win 3", 413);
- glutAddMenuEntry("destroy sub window", 414);
- glutAddMenuEntry("destroy color index win 6", 416);
- glutAddMenuEntry("destroy color index win 7", 417);
-
- /* Window manager stuff */
-
- menu5 = glutCreateMenu(menuFunc);
- glutAddMenuEntry("move current win", 430);
- glutAddMenuEntry("resize current win", 431);
- glutAddMenuEntry("iconify current win", 432);
- glutAddMenuEntry("show current win", 433);
- glutAddMenuEntry("hide current win", 434);
- glutAddMenuEntry("push current win", 435);
- glutAddMenuEntry("pop current win", 436);
- glutAddMenuEntry(" ", 9999);
- glutAddMenuEntry("move win 1", 420);
- glutAddMenuEntry("resize win 1", 421);
- glutAddMenuEntry("iconify win 1", 422);
- glutAddMenuEntry("show win 1", 423);
- glutAddMenuEntry("hide win 1", 424);
- glutAddMenuEntry("push win 1", 425);
- glutAddMenuEntry("pop win 1", 426);
-
- /* Gfx modes */
-
- createMenu6(); /* build dynamically */
-
- /* Texty reports */
-
- menu7 = glutCreateMenu(menuFunc);
- glutAddMenuEntry("report current win modes", 700);
- glutAddMenuEntry("report current device data", 701);
- glutAddMenuEntry("check OpenGL extensions", 702);
- glutAddMenuEntry("dump internal data (d)", 703);
-
- /* Play with menus */
-
- menu8 = glutCreateMenu(menuFunc);
- glutAddMenuEntry("toggle menus on left button", 805);
- glutAddMenuEntry("toggle menus on middle button", 806);
- glutAddMenuEntry("toggle menus on right button", 807);
- glutAddMenuEntry("---------------------------", 9999);
- glutAddMenuEntry("add plain items", 800);
- glutAddMenuEntry("add submenu items", 801);
- glutAddMenuEntry("change new entries to plain items", 802);
- glutAddMenuEntry("change new entries to submenus", 803);
- glutAddMenuEntry("remove all new items", 804);
- glutAddMenuEntry("---------------------------", 9999);
-
- /* Main menu */
-
- menu1 = glutCreateMenu(menuFunc);
- glutAddSubMenu("control", menu2);
- glutAddSubMenu("shapes", menu3);
- glutAddSubMenu("windows", menu4);
- glutAddSubMenu("window ops", menu5);
- glutAddSubMenu("gfx modes", menu6);
- glutAddSubMenu("reports", menu7);
- glutAddSubMenu("menus", menu8);
- glutAddMenuEntry("help (h)", 101);
- glutAddMenuEntry("quit (esc)", 100);
- }
-
- /* createMenu6 - Dynamically rebuild menu of display modes to
- show current choices */
-
- void
- createMenu6(void)
- {
- char str[100];
- int i;
-
- if (menu6 != 0)
- glutDestroyMenu(menu6);
- menu6 = glutCreateMenu(menuFunc);
-
- for (i = 0; i < MODES; i++) {
- sprintf(str, "%srequest %s", (modes[i] ? "+ " : " "), modeNames[i]);
- glutAddMenuEntry(str, 602 + i);
- }
- }
-
- /* menuFunc - Process return codes from popup menus */
-
- void
- menuFunc(int value)
- {
- static int initItems = 10;
- int items, m;
-
- if (initItems == 0) {
- glutSetMenu(menu8);
- initItems = glutGet(GLUT_MENU_NUM_ITEMS);
- }
- PR("Menu returned value %d \n", value);
-
- switch (value) {
-
- /* GLUT shapes */
-
- case 200:
- case 201:
- case 202:
- case 203:
- case 204:
- case 205:
- case 206:
- case 207:
- case 208:
- redefineShapes(value - 200);
- break;
-
- /* Overall controls */
-
- case 300:
- menuFreeze = !menuFreeze;
- break;
-
- case 301:
- text[idToIndex(glutGetWindow())] = !(text[idToIndex(glutGetWindow())]);
- break;
-
- case 302:
- timerOn = !timerOn;
- if (timerOn)
- glutTimerFunc(DELAY, timerFunc, 1);
- break;
-
- case 303:
- animation = !animation;
- if (animation)
- glutIdleFunc(idleFunc);
- else
- glutIdleFunc(NULL);
- break;
-
- case 304:
- winFreeze[idToIndex(glutGetWindow())] = !(winFreeze[idToIndex(
- glutGetWindow())]);
- break;
-
- case 305:
- debug = !debug;
- break;
-
- case 307:
- backdrop = !backdrop;
- break;
-
- case 308:
- passive = !passive;
- if (passive)
- glutPassiveMotionFunc(passiveMotionFunc);
- else
- glutPassiveMotionFunc(NULL);
- break;
-
- case 310:
- lineWidth += 1;
- updateAll();
- break;
-
- case 311:
- lineWidth -= 1;
- if (lineWidth < 1)
- lineWidth = 1;
- updateAll();
- break;
-
- case 312:
- demoMode = !demoMode;
- if (demoMode)
- autoDemo(-2);
- break;
-
- /* Window create/destroy. */
-
- /* Creates */
-
- case 400:
- makeWindow(0);
- break;
-
- case 401:
- makeWindow(1);
- break;
-
- case 402:
- makeWindow(2);
- break;
-
- case 403:
- makeWindow(3);
- break;
-
- case 404:
- makeWindow(4);
- break;
-
- case 406:
- makeWindow(6);
- break;
-
- case 407:
- makeWindow(7);
- break;
-
- /* Destroys */
-
- case 410:
- killWindow(0);
- break;
-
- case 411:
- killWindow(1);
- break;
-
- case 412:
- killWindow(2);
- break;
-
- case 413:
- killWindow(3);
- break;
-
- case 414:
- killWindow(4);
- break;
-
- case 416:
- killWindow(6);
- break;
-
- case 417:
- killWindow(7);
- break;
-
- case 450:
- makeAllWindows();
- break;
-
- case 451:
- killAllWindows();
- break;
-
- /* Window movements etc. */
-
- case 420:
- positionWindow(1);
- break;
-
- case 421:
- reshapeWindow(1);
- break;
-
- case 422:
- iconifyWindow(1);
- break;
-
- case 423:
- showWindow(1);
- break;
-
- case 424:
- hideWindow(1);
- break;
-
- case 425:
- pushWindow(1);
- break;
-
- case 426:
- popWindow(1);
- break;
-
- case 430:
- positionWindow(idToIndex(glutGetWindow()));
- break;
-
- case 431:
- reshapeWindow(idToIndex(glutGetWindow()));
- break;
-
- case 432:
- iconifyWindow(idToIndex(glutGetWindow()));
- break;
-
- case 433:
- showWindow(idToIndex(glutGetWindow()));
- break;
-
- case 434:
- hideWindow(idToIndex(glutGetWindow()));
- break;
-
- case 435:
- pushWindow(idToIndex(glutGetWindow()));
- break;
-
- case 436:
- popWindow(idToIndex(glutGetWindow()));
- break;
-
- /* Test gfx modes. */
-
- case 600:
- makeWindow(3);
- break;
-
- case 601:
- killWindow(3);
- break;
-
- case 602:
- case 603:
- case 604:
- case 605:
- case 606:
- case 607:
- case 608:
- case 609:
- case 610:
- case 611:
- modes[value - 602] = !modes[value - 602];
- setInitDisplayMode();
- break;
-
- /* Text reports */
-
- /* This is pretty ugly. */
-
- #define INDENT 30
- #define REPORTSTART(text) \
- printf("\n" text "\n"); \
- textPtr[0] = (char *)malloc(strlen(text)+1); \
- strcpy(textPtr[0], text); \
- textCount = 1;
-
- #define REPORTEND \
- scrollLine = 0; \
- textPtr[textCount] = NULL; \
- makeWindow(8); \
- updateText();
-
- #define GLUTGET(name) \
- { \
- char str[100], str2[100]; \
- int s, len; \
- sprintf(str, # name); \
- len = (int) strlen(# name); \
- for(s = 0 ; s < INDENT-len; s++) \
- strcat(str, " "); \
- sprintf(str2, ": %d\n",glutGet(name)); \
- strcat(str, str2); \
- printf(str); \
- textPtr[textCount] = stralloc(str); \
- textCount++; \
- }
-
- case 700:
-
- printf("XXXXXX glutGetWindow = %d\n", glutGetWindow());
- REPORTSTART("glutGet():");
-
- GLUTGET(GLUT_WINDOW_X);
- GLUTGET(GLUT_WINDOW_Y);
- GLUTGET(GLUT_WINDOW_WIDTH);
- GLUTGET(GLUT_WINDOW_HEIGHT);
- GLUTGET(GLUT_WINDOW_BUFFER_SIZE);
- GLUTGET(GLUT_WINDOW_STENCIL_SIZE);
- GLUTGET(GLUT_WINDOW_DEPTH_SIZE);
- GLUTGET(GLUT_WINDOW_RED_SIZE);
- GLUTGET(GLUT_WINDOW_GREEN_SIZE);
- GLUTGET(GLUT_WINDOW_BLUE_SIZE);
- GLUTGET(GLUT_WINDOW_ALPHA_SIZE);
- GLUTGET(GLUT_WINDOW_ACCUM_RED_SIZE);
- GLUTGET(GLUT_WINDOW_ACCUM_GREEN_SIZE);
- GLUTGET(GLUT_WINDOW_ACCUM_BLUE_SIZE);
- GLUTGET(GLUT_WINDOW_ACCUM_ALPHA_SIZE);
- GLUTGET(GLUT_WINDOW_DOUBLEBUFFER);
- GLUTGET(GLUT_WINDOW_RGBA);
- GLUTGET(GLUT_WINDOW_PARENT);
- GLUTGET(GLUT_WINDOW_NUM_CHILDREN);
- GLUTGET(GLUT_WINDOW_COLORMAP_SIZE);
- GLUTGET(GLUT_WINDOW_NUM_SAMPLES);
- GLUTGET(GLUT_STEREO);
- GLUTGET(GLUT_SCREEN_WIDTH);
- GLUTGET(GLUT_SCREEN_HEIGHT);
- GLUTGET(GLUT_SCREEN_HEIGHT_MM);
- GLUTGET(GLUT_SCREEN_WIDTH_MM);
- GLUTGET(GLUT_MENU_NUM_ITEMS);
- GLUTGET(GLUT_DISPLAY_MODE_POSSIBLE);
- GLUTGET(GLUT_INIT_DISPLAY_MODE);
- GLUTGET(GLUT_INIT_WINDOW_X);
- GLUTGET(GLUT_INIT_WINDOW_Y);
- GLUTGET(GLUT_INIT_WINDOW_WIDTH);
- GLUTGET(GLUT_INIT_WINDOW_HEIGHT);
- GLUTGET(GLUT_ELAPSED_TIME);
-
- REPORTEND;
- break;
-
- #define GLUTDEVGET(name) \
- { \
- char str[100], str2[100]; \
- int len, s; \
- sprintf(str, # name); \
- len = (int) strlen(# name); \
- for(s = 0 ; s < INDENT-len; s++) \
- strcat(str, " "); \
- sprintf(str2, ": %d\n", \
- glutDeviceGet(name)); \
- strcat(str, str2); \
- printf(str); \
- textPtr[textCount] = stralloc(str); \
- textCount++; \
- }
-
- case 701:
- REPORTSTART("glutDeviceGet():");
-
- GLUTDEVGET(GLUT_HAS_KEYBOARD);
- GLUTDEVGET(GLUT_HAS_MOUSE);
- GLUTDEVGET(GLUT_HAS_SPACEBALL);
- GLUTDEVGET(GLUT_HAS_DIAL_AND_BUTTON_BOX);
- GLUTDEVGET(GLUT_HAS_TABLET);
- GLUTDEVGET(GLUT_NUM_MOUSE_BUTTONS);
- GLUTDEVGET(GLUT_NUM_SPACEBALL_BUTTONS);
- GLUTDEVGET(GLUT_NUM_BUTTON_BOX_BUTTONS);
- GLUTDEVGET(GLUT_NUM_DIALS);
- GLUTDEVGET(GLUT_NUM_TABLET_BUTTONS);
-
- REPORTEND;
- break;
-
- #define EXTCHECK(name) \
- { \
- char str[100], str2[100]; \
- int len, s; \
- sprintf(str, # name); \
- len = (int) strlen(# name); \
- for(s = 0 ; s < INDENT-len; s++) \
- strcat(str, " "); \
- sprintf(str2, ": %s\n", \
- glutExtensionSupported(# name)? \
- "yes": "no"); \
- strcat(str, str2); \
- printf(str); \
- textPtr[textCount] = stralloc(str); \
- textCount++; \
- }
-
- case 702:
- REPORTSTART("glutExtensionSupported():");
-
- EXTCHECK(GL_EXT_abgr);
- EXTCHECK(GL_EXT_blend_color);
- EXTCHECK(GL_EXT_blend_minmax);
- EXTCHECK(GL_EXT_blend_logic_op);
- EXTCHECK(GL_EXT_blend_subtract);
- EXTCHECK(GL_EXT_polygon_offset);
- EXTCHECK(GL_EXT_texture);
- EXTCHECK(GL_EXT_guaranteed_to_fail);
- EXTCHECK(GLX_SGI_swap_control);
- EXTCHECK(GLX_SGI_video_sync);
- EXTCHECK(GLX_SGIS_multi_sample);
-
- REPORTEND;
- break;
-
- case 703:
- dumpIds();
- break;
-
- /* Mess around with menus */
-
- case 800:
- if (glutGetMenu() != menu8) /* just a test */
- printf("glutGetMenu() returned unexpected value\n");
- glutAddMenuEntry("help", 101);
- glutAddMenuEntry("help", 101);
- glutAddMenuEntry("help", 101);
- glutAddMenuEntry("help", 101);
- glutAddMenuEntry("help", 101);
- break;
-
- case 801:
- glutAddSubMenu("shapes", menu3);
- glutAddSubMenu("shapes", menu3);
- glutAddSubMenu("shapes (a long string to break menus with)", menu3);
- glutAddSubMenu("shapes", menu3);
- glutAddSubMenu("shapes", menu3);
- break;
-
- case 802:
- items = glutGet(GLUT_MENU_NUM_ITEMS);
- for (m = initItems + 1; m <= items; m++) {
- glutChangeToMenuEntry(m, "help", 101);
- }
- break;
-
- case 803:
- items = glutGet(GLUT_MENU_NUM_ITEMS);
- for (m = initItems + 1; m <= items; m++) {
- glutChangeToSubMenu(m, "shapes", menu3);
- }
- break;
-
- case 804:
- items = glutGet(GLUT_MENU_NUM_ITEMS);
- /* reverse order so renumbering not aproblem */
- for (m = items; m >= initItems + 1; m--) {
- glutRemoveMenuItem(m);
- }
- break;
-
- case 805:
- menuButton[0] = !menuButton[0];
- attachMenus();
- break;
-
- case 806:
- menuButton[1] = !menuButton[1];
- attachMenus();
- break;
-
- case 807:
- menuButton[2] = !menuButton[2];
- attachMenus();
- break;
-
- /* Direct menu items. */
-
- case 100:
- exit(0);
- break;
-
- case 101:
- if (winId[5] == 0)
- makeWindow(5);
- else
- killWindow(5);
- break;
-
- case 9999:
- break;
-
- default:
- fprintf(stderr, "\007Unhandled case %d in menu callback\n", value);
- }
-
- }
-
- /* redefineShapes - Remake the shapes display lists */
-
- void
- redefineShapes(int shape)
- {
- int i;
-
- #define C3 \
- switch(i) \
- { \
- case 0: \
- case 3: \
- C1; \
- break; \
- \
- case 1: \
- case 2: \
- case 4: \
- case 6: \
- case 7: \
- C2; \
- break; \
- } \
- currentShape = shape
-
- for (i = 0; i < MAXWIN; i++) {
- if (winId[i]) {
- glutSetWindow(winId[i]);
- if (glIsList(i + 1))
- glDeleteLists(i + 1, 1);
- glNewList(i + 1, GL_COMPILE);
-
- switch (shape) {
-
- #undef C1
- #define C1 glutSolidSphere(1.5, 10, 10)
- #undef C2
- #define C2 glutWireSphere(1.5, 10, 10)
-
- case 0:
- C3;
- break;
-
- #undef C1
- #define C1 glutSolidCube(2)
- #undef C2
- #define C2 glutWireCube(2)
-
- case 1:
- C3;
- break;
-
- #undef C1
- #define C1 glutSolidCone(1.5, 1.75, 10, 10);
- #undef C2
- #define C2 glutWireCone(1.5, 1.75, 10, 10);
-
- case 2:
- C3;
- break;
-
- #undef C1
- #define C1 glutSolidTorus(0.5, 1.1, 10, 10)
- #undef C2
- #define C2 glutWireTorus(0.5, 1.1, 10, 10)
-
- case 3:
- C3;
- break;
-
- #undef C1
- #define C1 glScalef(.8, .8, .8);glutSolidDodecahedron()
- #undef C2
- #define C2 glScalef(.8, .8, .8);glutWireDodecahedron()
-
- case 4:
- C3;
- break;
-
- #undef C1
- #define C1 glScalef(1.5, 1.5, 1.5);glutSolidOctahedron()
- #undef C2
- #define C2 glScalef(1.5, 1.5, 1.5);glutWireOctahedron()
-
- case 5:
- C3;
- break;
-
- #undef C1
- #define C1 glScalef(1.8, 1.8, 1.8);glutSolidTetrahedron()
- #undef C2
- #define C2 glScalef(1.8, 1.8, 1.8);glutWireTetrahedron()
-
- case 6:
- C3;
- break;
-
- #undef C1
- #define C1 glScalef(1.5, 1.5, 1.5);glutSolidIcosahedron()
- #undef C2
- #define C2 glScalef(1.5, 1.5, 1.5);glutWireIcosahedron()
-
- case 7:
- C3;
- break;
-
- #undef C1
- #define C1 glutSolidTeapot(1.5);
- #undef C2
- #define C2 glutWireTeapot(1.5);
-
- case 8:
- C3;
- break;
- }
- glEndList();
- }
- }
- }
-
- /* positionWindow - Shift a window */
-
- void
- positionWindow(int index)
- {
- int x, y;
-
- if (winId[index] == 0)
- return;
-
- glutSetWindow(winId[index]);
- x = glutGet(GLUT_WINDOW_X);
- y = glutGet(GLUT_WINDOW_Y);
- glutPositionWindow(x + 50, y + 50);
- }
-
- /* reshapeWindow - Change window size a little */
-
- void
- reshapeWindow(int index)
- {
- int x, y;
-
- if (winId[index] == 0)
- return;
- glutSetWindow(winId[index]);
- x = glutGet(GLUT_WINDOW_WIDTH);
- y = glutGet(GLUT_WINDOW_HEIGHT);
- /* glutReshapeWindow(x * (index % 2? 0.8: 1.2), y * (index % 2?
-
- 1.2: 0.8)); */
- glutReshapeWindow((int) (x * 1.0), (int) (y * 0.8));
- }
-
- /* iconifyWindow - Iconify a window */
-
- void
- iconifyWindow(int index)
- {
- if (winId[index] == 0)
- return;
- glutSetWindow(winId[index]);
- glutIconifyWindow();
- }
-
- /* showWindow - Show a window (map or uniconify it) */
-
- void
- showWindow(int index)
- {
- if (winId[index] == 0)
- return;
- glutSetWindow(winId[index]);
- glutShowWindow();
- }
-
- /* hideWindow - Hide a window (unmap it) */
-
- void
- hideWindow(int index)
- {
- if (winId[index] == 0)
- return;
- glutSetWindow(winId[index]);
- glutHideWindow();
- }
-
- /* pushWindow - Push a window */
-
- void
- pushWindow(int index)
- {
- if (winId[index] == 0)
- return;
- glutSetWindow(winId[index]);
- glutPushWindow();
- }
-
- /* popWindow - Pop a window */
-
- void
- popWindow(int index)
- {
- if (winId[index] == 0)
- return;
- glutSetWindow(winId[index]);
- glutPopWindow();
- }
-
- /* drawScene - Draw callback, triggered by expose events etc.
- in GLUT. */
-
- void
- drawScene(void)
- {
- int winIndex;
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- winIndex = idToIndex(glutGetWindow());
- /* printf("drawScene for index %d, id %d\n", winIndex,
- glutGetWindow()); */
-
- glPushMatrix();
- glLineWidth(lineWidth);
- if (backdrop)
- glCallList(100);
-
- /* Left button spinning */
-
- trackBall(APPLY, 0, 0, 0, 0);
-
- /* Apply continuous spinning */
-
- glRotatef(angle, 0, 1, 0);
-
- glCallList(winIndex + 1);
- glPopMatrix();
-
- if (text[winIndex])
- showText();
-
- glutSwapBuffers();
- }
-
- /* showText - Render some text in the current GLUT window */
-
- void
- showText(void)
- {
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- gluOrtho2D(0, 100, 0, 100);
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- glColor3f(1.0, 1.0, 1.0);
- glIndexi(7);
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_LIGHTING);
-
- glLineWidth(lineWidth);
-
- textString(1, 1, "GLUT_BITMAP_8_BY_13", GLUT_BITMAP_8_BY_13);
- textString(1, 5, "GLUT_BITMAP_9_BY_15", GLUT_BITMAP_9_BY_15);
- textString(1, 10, "GLUT_BITMAP_TIMES_ROMAN_10", GLUT_BITMAP_TIMES_ROMAN_10);
- textString(1, 15, "GLUT_BITMAP_TIMES_ROMAN_24", GLUT_BITMAP_TIMES_ROMAN_24);
-
- strokeString(1, 25, "GLUT_STROKE_ROMAN", GLUT_STROKE_ROMAN);
- strokeString(1, 35, "GLUT_STROKE_MONO_ROMAN", GLUT_STROKE_MONO_ROMAN);
-
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
-
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
- }
-
- /* textString - Bitmap font string */
-
- void
- textString(int x, int y, char *msg, void *font)
- {
- glRasterPos2f(x, y);
- while (*msg) {
- glutBitmapCharacter(font, *msg);
- msg++;
- }
- }
-
- /* strokeString - Stroke font string */
-
- void
- strokeString(int x, int y, char *msg, void *font)
- {
- glPushMatrix();
- glTranslatef(x, y, 0);
- glScalef(.04, .04, .04);
- while (*msg) {
- glutStrokeCharacter(font, *msg);
- msg++;
- }
- glPopMatrix();
- }
-
- /* idleFunc - GLUT idle func callback - animates windows */
-
- void
- idleFunc(void)
- {
- int i;
-
- if (!leftDown && !middleDown)
- angle += 1;
- angle = angle % 360;
-
- for (i = 0; i < MAXWIN; i++) {
- if (winId[i] && winVis[i] && !winFreeze[i]) {
- glutSetWindow(winId[i]);
- glutPostRedisplay();
- }
- }
- }
-
- /* reshapeFunc - Reshape callback. */
-
- void
- reshapeFunc(int width, int height)
- {
- int winId;
- float aspect;
-
- winId = glutGetWindow();
- PR("reshape callback for window id %d \n", winId);
-
- glViewport(0, 0, width, height);
- aspect = (float) width / height;
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(40.0, aspect, 1.0, 20.0);
- glMatrixMode(GL_MODELVIEW);
- }
-
- /* visible - Visibility callback. Turn off rendering in
- invisible windows */
-
- void
- visible(int state)
- {
- int winId;
- static GLboolean someVisible = GL_TRUE;
-
- winId = glutGetWindow();
- /* printf("visible: state = %d \n", state); */
-
- if (state == GLUT_VISIBLE) {
- PR("Window id %d visible \n", winId);
- winVis[idToIndex(winId)] = GL_TRUE;
- } else {
- PR("Window %d not visible \n", winId);
- winVis[idToIndex(winId)] = GL_FALSE;
- }
-
- if ((winVis[0] == GL_FALSE) && (winVis[1] == GL_FALSE) && (winVis[2] == GL_FALSE)
- && (winVis[3] == GL_FALSE) && (winVis[6] == GL_FALSE) && (winVis[7] ==
- GL_FALSE)) {
- glutIdleFunc(NULL);
- PR("All windows not visible; idle func disabled\n");
- someVisible = GL_FALSE;
- } else {
- if (!someVisible) {
- PR("Some windows now visible; idle func enabled\n");
- someVisible = GL_TRUE;
- if (animation)
- glutIdleFunc(idleFunc);
- }
- }
- }
-
- /* keyFunc - Ascii key callback */
-
- /* ARGSUSED1 */
- void
- keyFunc(unsigned char key, int x, int y)
- {
- int i, ii;
-
- if (debug || showKeys)
- printf("Ascii key '%c' 0x%02x\n", key, key);
-
- switch (key) {
- case 0x1b:
- exit(0);
- break;
-
- case 'a':
- demoMode = !demoMode;
- if (demoMode)
- autoDemo(-2);
- break;
-
- case 's':
- AUTODELAY = AUTODELAY * 0.666;
- break;
-
- case 'S':
- AUTODELAY = AUTODELAY * 1.5;
- break;
-
- case 'q':
- killWindow(idToIndex(glutGetWindow()));
- break;
-
- case 'k':
- showKeys = !showKeys;
- break;
-
- case 'p':
- demoMode = !demoMode;
- if (demoMode)
- autoDemo(-999);
- break;
-
- case 'D':
- debug = !debug;
- break;
-
- case 'd':
- dumpIds();
- break;
-
- case 'h':
- if (winId[5] == 0)
- makeWindow(5);
- else
- killWindow(5);
- break;
-
- case 't':
- ii = idToIndex(glutGetWindow());
- text[ii] = !text[ii];
- break;
-
- case 'r':
- trackBall(RESET, 0, 0, 0, 0);
- break;
-
- case 'l':
- lineWidth += 1;
- updateAll();
- break;
-
- case 'L':
- lineWidth -= 1;
- if (lineWidth < 1)
- lineWidth = 1;
- updateAll();
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '6':
- i = key - '0';
- winVis[i] = !winVis[i];
- break;
-
- case ')':
- makeWindow(0);
- break;
-
- case '!':
- makeWindow(1);
- break;
-
- case '@':
- makeWindow(2);
- break;
-
- case '#':
- makeWindow(3);
- break;
-
- }
- }
-
- /* specialFunc - Special keys callback (F keys, cursor keys
- etc. */
-
- /* ARGSUSED1 */
- void
- specialFunc(int key, int x, int y)
- {
- if (debug || showKeys)
- printf("Special key %d\n", key);
-
- switch (key) {
- case GLUT_KEY_PAGE_DOWN:
- scrollLine += 10;
- updateHelp();
- updateText();
- break;
-
- case GLUT_KEY_PAGE_UP:
- scrollLine -= 10;
- updateHelp();
- updateText();
- break;
-
- case GLUT_KEY_DOWN:
- scrollLine += 1;
- updateHelp();
- updateText();
- break;
-
- case GLUT_KEY_UP:
- scrollLine -= 1;
- updateHelp();
- updateText();
- break;
-
- case GLUT_KEY_HOME:
- scrollLine = 0;
- updateHelp();
- updateText();
- break;
-
- case GLUT_KEY_END:
- scrollLine = 9999;
- updateHelp();
- updateText();
- break;
-
- case GLUT_KEY_RIGHT:
- scrollCol -= 1;
- updateHelp();
- updateText();
- break;
-
- case GLUT_KEY_LEFT:
- scrollCol += 1;
- updateHelp();
- updateText();
- break;
- }
- }
-
- /* mouseFunc - Mouse button callback */
-
- void
- mouseFunc(int button, int state, int x, int y)
- {
- PR("Mouse button %d, state %d, at pos %d, %d\n", button, state, x, y);
-
- trackBall(MOUSEBUTTON, button, state, x, y);
- }
-
- /* motionFunc - Mouse movement (with a button down) callback */
-
- void
- motionFunc(int x, int y)
- {
- PR("Mouse motion at %d, %d\n", x, y);
-
- trackBall(MOUSEMOTION, 0, 0, x, y);
-
- glutPostRedisplay();
- }
-
- /* passiveMotionFunc - Mouse movement (with no button down)
- callback */
-
- void
- passiveMotionFunc(int x, int y)
- {
- printf("Mouse motion at %d, %d\n", x, y);
- }
-
- /* entryFunc - Window entry event callback */
-
- void
- entryFunc(int state)
- {
- int winId = glutGetWindow();
- PR("Entry event: window id %d (index %d), state %d \n", winId, idToIndex(
- winId), state);
- }
-
- /* menuStateFunc - Callback to tell us when menus are popped
- up/down. */
-
- int menu_state = GLUT_MENU_NOT_IN_USE;
-
- void
- menuStateFunc(int state)
- {
- printf("menu stated = %d\n", state);
- menu_state = state;
-
- if (glutGetWindow() == 0) {
- PR("menuStateFunc: window invalid\n");
- return;
- }
- PR("Menus are%sin use\n", state == GLUT_MENU_IN_USE ? " " : " not ");
-
- if ((state == GLUT_MENU_IN_USE) && menuFreeze)
- glutIdleFunc(NULL);
- else if (animation)
- glutIdleFunc(idleFunc);
- }
-
- /* timerFunc - General test of global timer */
-
- void
- timerFunc(int value)
- {
- printf("timer callback: value %d\n", value);
- if (timerOn) {
- glutTimerFunc(DELAY, timerFunc, 1);
- }
- }
-
- #if 0
- /* delayedReinstateMenuStateCallback - Hack to reinstate
- MenuStateCallback after a while. */
-
- void
- delayedReinstateMenuStateCallback(int state)
- {
- glutMenuStateFunc(menuStateFunc);
- }
-
- #endif
-
- /* setInitDisplayMode - update display modes from display mode
- menu */
-
- void
- setInitDisplayMode(void)
- {
- int i;
-
- displayMode = 0;
-
- for (i = 0; i < MODES; i++) {
- if (modes[i]) {
- /* printf("Requesting %s \n", modeNames[i]); */
- displayMode |= glutMode[i];
- }
- }
-
- glutInitDisplayMode(displayMode);
-
- createMenu6();
- if (!glutGet(GLUT_DISPLAY_MODE_POSSIBLE))
- warning("This display mode not supported\n");
- }
-
- /* makeWindow - Create one of the windows */
-
- void
- makeWindow(int index)
- {
- char str[99];
-
- if (winId[index] != 0) {
- /* warning("Attempt to create window which is already
- created"); */
- return;
- }
- switch (index) {
-
- case 0: /* ordinary RGB windows */
- case 1:
- case 2:
- case 3:
-
- setInitDisplayMode();
- glutInitWindowPosition(pos[index][0], pos[index][1]);
- glutInitWindowSize(size[index][0], size[index][1]);
- winId[index] = glutCreateWindow(" ");
- PR("Window %d id = %d \n", index, winId[index]);
- gfxInit(index);
-
- addCallbacks();
-
- sprintf(str, "window %d (RGB)", index);
- glutSetWindowTitle(str);
- sprintf(str, "icon %d", index);
- glutSetIconTitle(str);
- glutSetMenu(menu1);
- glutAttachMenu(GLUT_RIGHT_BUTTON);
- break;
-
- case 4: /* subwindow */
-
- setInitDisplayMode();
- winId[index] = glutCreateSubWindow(winId[0], pos[index][0], pos[index]
- [1], size[index][0], size[index][1]);
- PR("Window %d id = %d \n", index, winId[index]);
- gfxInit(index);
- glutDisplayFunc(drawScene);
- glutVisibilityFunc(visible);
- glutReshapeFunc(reshapeFunc);
-
- break;
-
- case 5: /* help window */
- case 8: /* text window */
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
- glutInitWindowPosition(pos[index][0], pos[index][1]);
- glutInitWindowSize(size[index][0], size[index][1]);
- winId[index] = glutCreateWindow(" ");
- PR("Window %d id = %d \n", index, winId[index]);
-
- /* addCallbacks(); */
- glutKeyboardFunc(keyFunc);
- glutSpecialFunc(specialFunc);
-
- glClearColor(0.15, 0.15, 0.15, 1.0);
- glColor3f(1, 1, 1);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluOrtho2D(0, 300, 0, 100);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- if (index == 5) {
- glutDisplayFunc(updateHelp);
- glutSetWindowTitle("help (RGB) win 5");
- glutSetIconTitle("help");
- } else {
- glutDisplayFunc(updateText);
- glutSetWindowTitle("text (RGB) win 8");
- glutSetIconTitle("text");
- }
- glutSetMenu(menu1);
- glutAttachMenu(GLUT_RIGHT_BUTTON);
- break;
-
- case 6: /* color index window */
- case 7: /* color index window */
-
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_INDEX | GLUT_DEPTH);
- glutInitWindowPosition(pos[index][0], pos[index][1]);
- glutInitWindowSize(size[index][0], size[index][1]);
- winId[index] = glutCreateWindow(" ");
- PR("Window %d id = %d \n", index, winId[index]);
-
- gfxInit(index);
-
- addCallbacks();
-
- sprintf(str, "window %d (color index)", index);
- glutSetWindowTitle(str);
- sprintf(str, "icon %d", index);
- glutSetIconTitle(str);
- glutSetMenu(menu1);
- glutAttachMenu(GLUT_RIGHT_BUTTON);
- break;
-
- }
- }
-
- /* killWindow - Kill one of the main windows */
-
- void
- killWindow(int index)
- {
- int i;
-
- if (winId[index] == 0) {
- /* fprintf(stderr, "Attempt to kill invalid window in
- killWindow\n"); */
- return;
- }
- PR("Killing win %d\n", index);
- glutSetWindow(winId[index]);
-
- /* Disable all callbacks for safety, although
- glutDestroyWindow should do this. */
-
- removeCallbacks();
-
- glutDestroyWindow(winId[index]);
- winId[index] = 0;
- winVis[index] = GL_FALSE;
-
- #if 0
- /* If we reinstate the menu state func here, prog breaks. So
- reinstate it a little later. */
- glutTimerFunc(MENUDELAY, delayedReinstateMenuStateCallback, 1);
- #endif
-
- if (index == 5) { /* help */
- scrollLine = 0;
- scrollCol = 0;
- }
- if (index == 8) { /* text window */
- for (i = 0; textPtr[i] != NULL; i++) {
- free(textPtr[i]); /* free the text strings */
- textPtr[i] = NULL;
- }
- }
- }
-
- /* addCallbacks - Add some standard callbacks after creating a
- window */
-
- void
- addCallbacks(void)
- {
- glutDisplayFunc(drawScene);
- glutVisibilityFunc(visible);
- glutReshapeFunc(reshapeFunc);
- glutKeyboardFunc(keyFunc);
- glutSpecialFunc(specialFunc);
- glutMouseFunc(mouseFunc);
- glutMotionFunc(motionFunc);
- glutEntryFunc(entryFunc);
-
- /* Callbacks for exotic input devices. Must get my dials &
- buttons back. */
-
- glutSpaceballMotionFunc(spaceballMotionCB);
- glutSpaceballRotateFunc(spaceballRotateCB);
- glutSpaceballButtonFunc(spaceballButtonCB);
-
- glutButtonBoxFunc(buttonBoxCB);
- glutDialsFunc(dialsCB);
-
- glutTabletMotionFunc(tabletMotionCB);
- glutTabletButtonFunc(tabletButtonCB);
- }
-
- /* removeCallbacks - Remove all callbacks before destroying a
- window. GLUT probably does this anyway but we'll be safe. */
-
- void
- removeCallbacks(void)
- {
- glutVisibilityFunc(NULL);
- glutReshapeFunc(NULL);
- glutKeyboardFunc(NULL);
- glutSpecialFunc(NULL);
- glutMouseFunc(NULL);
- glutMotionFunc(NULL);
- glutEntryFunc(NULL);
- }
-
- /* updateHelp - Update the help window after user scrolls. */
-
- void
- updateHelp(void)
- {
- static char *helpPtr[] =
- {
- "(Use PGUP, PGDN, HOME, END, arrows to scroll help text) ",
- " ",
- "A demo program for GLUT. ",
- "G Edwards, Aug 95 ",
- "Exercises 99% of GLUT calls ",
- VERSIONLONG,
- " ",
- "This text uses GLUT_STROKE_MONO_ROMAN font, a built-in vector font.",
- "(Try resizing the help window). ",
- " ",
- "Keys: ",
- " esc quit ",
- " t toggle text on/off in each window ",
- " h toggle help ",
- " q quit current window ",
- " a auto demo ",
- " p pause/unpause demo ",
- " l increase line width (gfx & stroke text) ",
- " L decrease line width (gfx & stroke text) ",
- " r reset transforms ",
- " k show keyboard events ",
- " D show all events ",
- " ",
- "Mouse: ",
- " Left button: rotate ",
- " Middle button: pan ",
- " Left + middle: zoom ",
- NULL};
-
- updateScrollWindow(5, helpPtr);
- }
-
- /* updateText - Update a text window */
-
- void
- updateText(void)
- {
- int i;
-
- if (textPtr[0] == NULL) {
- for (i = 0; i < 20; i++) {
- textPtr[i] = (char *) malloc(50);
- strcpy(textPtr[i], "no current text");
- }
- textPtr[20] = NULL;
- }
- updateScrollWindow(8, textPtr);
- }
-
- /* updateScrollWindow */
-
- void
- updateScrollWindow(int index, char **ptr)
- {
- int i, j, lines = 0;
-
- if (winId[index] == 0)
- return;
-
- glutSetWindow(winId[index]);
-
- for (i = 0; ptr[i] != NULL; i++)
- lines++;
-
- if (scrollLine < 0)
- scrollLine = 0;
- if (scrollLine > (lines - 5))
- scrollLine = lines - 5;
-
- glClear(GL_COLOR_BUFFER_BIT);
-
- glLineWidth(lineWidth);
-
- for (i = scrollLine, j = 1; ptr[i] != NULL; i++, j++)
- strokeString(scrollCol * 50, 100 - j * 6, ptr[i],
- GLUT_STROKE_MONO_ROMAN);
-
- glutSwapBuffers();
-
- }
-
- /* updateAll - Update all visible windows after soem global
- change, eg. line width */
-
- void
- updateAll(void)
- {
- int i;
-
- if (winId[5] != 0)
- updateHelp();
-
- if (winId[8] != 0)
- updateText();
-
- for (i = 0; i < MAXWIN; i++)
- if (winId[i]) {
- glutSetWindow(winId[i]);
- glutPostRedisplay();
- }
- }
-
- /* idToIndex - Convert GLUT window id to our internal index */
-
- int
- idToIndex(int id)
- {
- int i;
- for (i = 0; i < MAXWIN; i++) {
- if (winId[i] == id)
- return i;
- }
- fprintf(stderr, "error: id %d not found \n", id);
- return (-1);
- }
-
- /* warning - warning messages */
-
- void
- warning(char *msg)
- {
- fprintf(stderr, "\007");
-
- if (debug) {
- fprintf(stderr, "%s", msg);
- if (msg[strlen(msg)] != '\n')
- fprintf(stderr, "%s", "\n");
- }
- }
-
- /* dumpIds - Debug: dump some internal data */
-
- void
- dumpIds(void)
- {
- int i, j;
-
- printf("\nInternal data:\n");
-
- for (i = 0; i < MAXWIN; i++)
- printf("Index %d, glut win id %d, visibility %d\n", i, winId[i],
- winVis[i]);
-
- for (i = 0; i < MAXWIN; i++) {
- if (winId[i])
- glutSetWindow(winId[i]);
- else {
- printf("index %d - no glut window\n", i);
- continue;
- }
-
- for (j = 1; j <= MAXWIN; j++)
- printf("Index %d, display list %d %s defined\n", i, j, glIsList(j) ?
- "is " : "not");
- }
- }
-
- /* autoDemo - Run auto demo/test This is a bit tricky. We need
- to start a timer sequence which progressively orders things
- to be done. The work really gets done when we return from
- our callback. Have to think about the event loop / callback
- design here. */
-
- void
- autoDemo(int value)
- {
-
- #define STEP(a, b) \
- case a: \
- action(a); \
- glutTimerFunc(AUTODELAY * b, autoDemo, next(a); \
- break;
-
- static int index = 0;
- static int count = 0;
- static int restartValue = -2;
-
- if (value == -999)
- value = restartValue;
-
- restartValue = value;
-
- #define AUTODELAY2 (unsigned int) (AUTODELAY*0.66)
-
- /* fprintf(stderr, "autoDemo: value %d \n", value); */
-
- if (!demoMode)
- return;
-
- if (menu_state == GLUT_MENU_IN_USE) {
- glutTimerFunc(AUTODELAY / 2, autoDemo, value);
- return;
- }
- switch (value) {
-
- /* Entry point; kill off existing windows. */
-
- case -2:
- killAllWindows();
- glutTimerFunc(AUTODELAY / 2, autoDemo, 1);
- break;
-
- /* Start making windows */
-
- case -1:
- makeWindow(0);
- glutTimerFunc(AUTODELAY, autoDemo, 0); /* skip case 0
- first time */
- break;
-
- /* Change shape & backdrop */
-
- case 0:
- currentShape = (currentShape + 1) % 9;
- redefineShapes(currentShape);
- count += 1;
- if (count % 2)
- backdrop = !backdrop;
- glutTimerFunc(AUTODELAY, autoDemo, 1);
- break;
-
- /* Keep making windows */
-
- case 1:
- makeWindow(1);
- glutTimerFunc(AUTODELAY, autoDemo, 2);
- break;
-
- case 2:
- makeWindow(2);
- glutTimerFunc(AUTODELAY, autoDemo, 3);
- break;
-
- case 3:
- makeWindow(3);
- glutTimerFunc(AUTODELAY, autoDemo, 4);
- break;
-
- case 4:
- makeWindow(4);
- glutTimerFunc(AUTODELAY, autoDemo, 5);
- break;
-
- case 5:
- makeWindow(5);
- glutTimerFunc(AUTODELAY * 2, autoDemo, 51);
- break;
-
- case 51:
- makeWindow(6);
- glutTimerFunc(AUTODELAY * 2, autoDemo, 52);
- break;
-
- case 52:
- makeWindow(7);
- glutTimerFunc(AUTODELAY * 2, autoDemo, 53);
- break;
-
- /* Kill last 3 windows, leave 4 up. */
-
- case 53:
- killWindow(7);
- glutTimerFunc(AUTODELAY, autoDemo, 54);
- break;
-
- case 54:
- killWindow(6);
- glutTimerFunc(AUTODELAY, autoDemo, 6);
- break;
-
- case 6:
- killWindow(5);
- glutTimerFunc(AUTODELAY, autoDemo, 7);
- break;
-
- case 7:
- killWindow(4);
- glutTimerFunc(AUTODELAY, autoDemo, 700);
- break;
-
- /* Change shape again */
-
- case 700:
- currentShape = (currentShape + 1) % 9;
- redefineShapes(currentShape);
- glutTimerFunc(AUTODELAY, autoDemo, 701);
- break;
-
- /* Cycle 4 main windows through various window ops. */
-
- case 701:
- positionWindow(index);
- index = (index + 1) % 4;
- glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 701 : 702);
- break;
-
- case 702:
- reshapeWindow(index);
- index = (index + 1) % 4;
- glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 702 : 703);
- break;
-
- case 703:
- iconifyWindow(index);
- index = (index + 1) % 4;
- glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 703 : 704);
- break;
-
- case 704:
- showWindow(index);
- index = (index + 1) % 4;
- glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 704 : 705);
- break;
-
- case 705:
- hideWindow(index);
- index = (index + 1) % 4;
- glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 705 : 706);
- break;
-
- case 706:
- showWindow(index);
- index = (index + 1) % 4;
- glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 706 : 707);
- break;
-
- case 707:
- pushWindow(index);
- index = (index + 1) % 4;
- glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 707 : 708);
- break;
-
- case 708:
- popWindow(index);
- index = (index + 1) % 4;
- glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 708 : 8);
- break;
-
- /* Kill all windows */
-
- case 8:
- killWindow(3);
- glutTimerFunc(AUTODELAY, autoDemo, 9);
- break;
-
- case 9:
- killWindow(2);
- glutTimerFunc(AUTODELAY, autoDemo, 10);
- break;
-
- case 10:
- killWindow(1);
- glutTimerFunc(AUTODELAY, autoDemo, 11);
- break;
-
- case 11:
- killWindow(0);
- glutTimerFunc(AUTODELAY, autoDemo, -1); /* back to start */
- break;
- }
-
- }
-
- /* attachMenus - Attach/detach menus to/from mouse buttons */
-
- void
- attachMenus(void)
- {
- int i, b;
- int button[3] =
- {GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON};
-
- for (i = 0; i < MAXWIN; i++) {
- if (winId[i] != 0) {
- for (b = 0; b < 3; b++) {
- glutSetWindow(winId[i]);
- glutSetMenu(menu1);
- if (menuButton[b])
- glutAttachMenu(button[b]);
- else
- glutDetachMenu(button[b]);
- }
- }
- }
- }
-
- /* killAllWindows - Kill all windows (except 0) */
-
- void
- killAllWindows(void)
- {
- int w;
-
- for (w = 1; w < MAXWIN; w++)
- if (winId[w])
- killWindow(w);
- }
-
- /* makeAllWindows - Make all windows */
-
- void
- makeAllWindows(void)
- {
- int w;
-
- for (w = 0; w < MAXWIN; w++)
- if (!winId[w])
- makeWindow(w);
- }
-
- /* checkArgs - Check command line args */
-
- void
- checkArgs(int argc, char *argv[])
- {
- int argp;
- GLboolean quit = GL_FALSE;
- GLboolean error = GL_FALSE;
-
- #define AA argv[argp]
-
- #if 0
- #define NEXT argp++; \
- if(argp >= argc) \
- { \
- Usage(); \
- Exit(1); \
- }
- #endif
-
- argp = 1;
- while (argp < argc) {
- if (match(AA, "-help")) {
- commandLineHelp();
- quit = GL_TRUE;
- } else if (match(AA, "-version")) {
- printf(VERSIONLONG "\n");
- quit = GL_TRUE;
- } else if (match(AA, "-auto")) {
- demoMode = GL_TRUE;
- } else if (match(AA, "-scale")) {
- argp++;
- scaleFactor = atof(argv[argp]);
- } else {
- fprintf(stderr, "Unknown arg: %s\n", AA);
- error = GL_TRUE;
- quit = GL_TRUE;
- }
- argp++;
- }
-
- if (error) {
- commandLineHelp();
- exit(1);
- }
- if (quit)
- exit(0);
- }
-
- /* commandLineHelp - Command line help */
-
- void
- commandLineHelp(void)
- {
- printf("Usage:\n");
- printf(" -h[elp] this stuff\n");
- printf(" -v[ersion] show version\n");
- printf(" -a[uto] start in auto demo mode\n");
- printf(" -s[cale] f scale windows by f\n");
- printf("Standard GLUT args:\n");
- printf(" -iconic start iconic\n");
- printf(" -display DISP use display DISP\n");
- printf(" -direct use direct rendering (default)\n");
- printf(" -indirect use indirect rendering\n");
- printf(" -sync use synchronous X protocol\n");
- printf(" -gldebug check OpenGL errors\n");
- printf(" -geometry WxH+X+Y standard X window spec (overridden here) \n");
- }
-
- /* match - Match a string (any unique substring). */
-
- GLboolean
- match(char *arg, char *t)
- {
- if (strstr(t, arg))
- return GL_TRUE;
- else
- return GL_FALSE;
- }
-
- /* scaleWindows - Scale initial window sizes ansd positions */
-
- void
- scaleWindows(float scale)
- {
- int i;
-
- for (i = 0; i < MAXWIN; i++) {
- pos[i][0] = pos[i][0] * scale;
- pos[i][1] = pos[i][1] * scale;
- size[i][0] = size[i][0] * scale;
- size[i][1] = size[i][1] * scale;
- }
- }
-
- /* trackBall - A simple trackball (not with proper rotations). */
-
- /** A simple trackball with spin = left button
- pan = middle button
- zoom = left + middle
- Doesn't have proper trackball rotation, ie axes which remain fixed in
- the scene. We should use the trackball code from 4Dgifts. */
-
- #define STARTROTATE(x, y) \
- { \
- startMX = x; \
- startMY = y; \
- }
-
- #define STOPROTATE(x, y) \
- { \
- steadyXangle = varXangle; \
- steadyYangle = varYangle; \
- }
-
- #define STARTPAN(x, y) \
- { \
- startMX = x; \
- startMY = y; \
- }
-
- #define STOPPAN(x, y) \
- { \
- steadyX = varX; \
- steadyY = varY; \
- }
-
- #define STARTZOOM(x, y) \
- { \
- startMX = x; \
- startMY = y; \
- }
-
- #define STOPZOOM(x, y) \
- { \
- steadyZ = varZ; \
- }
-
- static float
- fixAngle(float angle)
- {
- return angle - floor(angle / 360.0) * 360.0;
- }
-
- void
- trackBall(int mode, int button, int state, int x, int y)
- {
- static int startMX = 0, startMY = 0; /* initial mouse pos */
- static int deltaMX = 0, deltaMY = 0; /* initial mouse pos */
- static float steadyXangle = 0.0, steadyYangle = 0.0;
- static float varXangle = 0.0, varYangle = 0.0;
- static float steadyX = 0.0, steadyY = 0.0, steadyZ = 0.0;
- static float varX = 0.0, varY = 0.0, varZ = 0.0;
-
- switch (mode) {
-
- case RESET:
- steadyXangle = steadyYangle = steadyX = steadyY = steadyZ = 0.0;
- break;
-
- case MOUSEBUTTON:
-
- if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && !middleDown) {
- STARTROTATE(x, y);
- leftDown = GL_TRUE;
- } else if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN &&
- middleDown) {
- STOPPAN(x, y);
- STARTZOOM(x, y);
- leftDown = GL_TRUE;
- } else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN &&
- !leftDown) {
- STARTPAN(x, y);
- middleDown = GL_TRUE;
- } else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN &&
- leftDown) {
- STOPROTATE(x, y);
- STARTZOOM(x, y);
- middleDown = GL_TRUE;
- } else if (state == GLUT_UP && button == GLUT_LEFT_BUTTON && !middleDown) {
- STOPROTATE(x, y);
- leftDown = GL_FALSE;
- } else if (state == GLUT_UP && button == GLUT_LEFT_BUTTON && middleDown) {
- STOPZOOM(x, y);
- STARTROTATE(x, y);
- leftDown = GL_FALSE;
- } else if (state == GLUT_UP && button == GLUT_MIDDLE_BUTTON && !leftDown) {
- STOPPAN(x, y);
- middleDown = GL_FALSE;
- } else if (state == GLUT_UP && button == GLUT_MIDDLE_BUTTON && leftDown) {
- STOPZOOM(x, y);
- STARTROTATE(x, y);
- middleDown = GL_FALSE;
- }
- break;
-
- case APPLY:
-
- if (leftDown && !middleDown) {
- glTranslatef(steadyX, steadyY, steadyZ);
- glRotatef(varXangle, 0, 1, 0);
- glRotatef(varYangle, 1, 0, 0);
- }
- /* Middle button pan */
-
- else if (middleDown && !leftDown) {
- glTranslatef(varX, varY, steadyZ);
- glRotatef(steadyXangle, 0, 1, 0);
- glRotatef(steadyYangle, 1, 0, 0);
- }
- /* Left + middle zoom. */
-
- else if (leftDown && middleDown) {
- glTranslatef(steadyX, steadyY, varZ);
- glRotatef(steadyXangle, 0, 1, 0);
- glRotatef(steadyYangle, 1, 0, 0);
- }
- /* Nothing down. */
-
- else {
- glTranslatef(steadyX, steadyY, steadyZ);
- glRotatef(steadyXangle, 0, 1, 0);
- glRotatef(steadyYangle, 1, 0, 0);
- }
- break;
-
- case MOUSEMOTION:
-
- deltaMX = x - startMX;
- deltaMY = startMY - y;
-
- if (leftDown && !middleDown) {
- varXangle = fixAngle(steadyXangle + deltaMX);
- varYangle = fixAngle(steadyYangle + deltaMY);
- } else if (middleDown && !leftDown) {
- varX = steadyX + deltaMX / 100.0;
- varY = steadyY + deltaMY / 100.0;
- } else if (leftDown && middleDown) {
- varZ = steadyZ - deltaMY / 50.0;
- }
- break;
- }
-
- }
-
- /* Callbacks for exotic input devices. These have not been
- tested yet owing to the usual complete absence of such
- devices in the UK support group. */
-
- /* spaceballMotionCB */
-
- void
- spaceballMotionCB(int x, int y, int z)
- {
- printf("spaceballMotionCB: translations are X %d, Y %d, Z %d\n", x, y, z);
- }
-
- /* spaceballRotateCB */
-
- void
- spaceballRotateCB(int x, int y, int z)
- {
- printf("spaceballRotateCB: rotations are X %d, Y %d, Z %d\n", x, y, z);
- }
-
- /* spaceballButtonCB */
-
- void
- spaceballButtonCB(int button, int state)
- {
- printf("spaceballButtonCB: button %d, state %d\n", button, state);
- }
-
- /* buttonBoxCB */
-
- void
- buttonBoxCB(int button, int state)
- {
- printf("buttonBoxCB: button %d, state %d\n", button, state);
- }
-
- /* dialsCB */
-
- void
- dialsCB(int dial, int value)
- {
- printf("dialsCB: dial %d, value %d\n", dial, value);
- }
-
- /* tabletMotionCB */
-
- void
- tabletMotionCB(int x, int y)
- {
- printf("tabletMotionCB: X %d, Y %d\n", x, y);
- }
-
- /* tabletButtonCB */
-
- /* ARGSUSED2 */
- void
- tabletButtonCB(int button, int state, int dummy1, int dummy2)
- {
- printf("tabletButtonCB: button %d, state %d\n", button, state);
- }
-